這段程式碼建立了一個具有互動效果的網頁,當你點擊每個面板時,面板會擴展並顯示隱藏的文字
完成圖:
HTML
將這個頁面分成5大區,每個大區裡面再分別有3個小區
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>Flex Panels 💪</title>
<link href='https://fonts.googleapis.com/css?family=Amatic+SC' rel='stylesheet' type='text/css'>
</head>
<body>
...
<div class="panels">
<div class="panel panel1">
<p>Hey</p>
<p>Let's</p>
<p>Dance</p>
</div>
<div class="panel panel2">
<p>Give</p>
<p>Take</p>
<p>Receive</p>
</div>
<div class="panel panel3">
<p>Experience</p>
<p>It</p>
<p>Today</p>
</div>
<div class="panel panel4">
<p>Give</p>
<p>All</p>
<p>You can</p>
</div>
<div class="panel panel5">
<p>Life</p>
<p>In</p>
<p>Motion</p>
</div>
</div>
...
</body>
</html>
CSS
html 和 body 設置了整體的樣式,包括背景顏色和字體。
.panels 使用 flex 佈局,使所有面板水平排列。
.panel 設置了背景顏色、陰影、字體顏色、對齊方式以及過渡效果。flex: 1 使面板平均分配空間,transition 設置了過渡效果。
panel1 到 panel5 設置了不同的背景圖片。
.panel > * 設置了面板內部元素的樣式和過渡效果。
.panel > *:first-child 和 .panel > *:last-child 設置了內部文字的初始位置,當面板打開時,它們會移動到中間。
html {
box-sizing: border-box;
background: #ffc600;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
}
body {
margin: 0;
}
*, *:before, *:after {
box-sizing: inherit;
}
.panels {
min-height: 100vh;
overflow: hidden;
display: flex;
}
.panel {
background: #6B0F9C;
box-shadow: inset 0 0 0 5px rgba(255, 255, 255, 0.1);
color: white;
text-align: center;
align-items: center;
transition: font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11), flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11), background 0.2s;
font-size: 20px;
background-size: cover;
background-position: center;
flex: 1;
justify-content: center;
align-items: center;
display: flex;
flex-direction: column;
}
.panel1 { background-image: url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500); }
.panel2 { background-image: url(https://source.unsplash.com/rFKUFzjPYiQ/1500x1500); }
.panel3 { background-image: url(https://memeprod.sgp1.digitaloceanspaces.com/user-wtf/1591615571903.jpg); }
.panel4 { background-image: url(https://source.unsplash.com/ITjiVXcwVng/1500x1500); }
.panel5 { background-image: url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500); }
.panel > * {
margin: 0;
width: 100%;
transition: transform 0.5s;
border: 1px solid red;
flex: 1 0 auto;
justify-content: center;
align-items: center;
display: flex;
}
.panel > *:first-child { transform: translateY(-100%); }
.panel.open-active > *:first-child { transform: translateY(0); }
.panel > *:last-child { transform: translateY(100%); }
.panel.open-active > *:last-child { transform: translateY(0); }
.panel p {
text-transform: uppercase;
font-family: 'Amatic SC', cursive;
text-shadow: 0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45);
font-size: 2em;
}
.panel p:nth-child(2) {
font-size: 4em;
}
.panel.open {
font-size: 40px;
flex: 5;
}
Javascript
選取所有具有panel class的元素。
定義一個函數toggleOpen,當面板被點擊時,切換open class,這會改變面板的大小。
定義一個函數toggleActive,當過渡效果結束且過渡的屬性名稱包含flex時,切換open-active class,這會改變面板內文本的顯示。
為每個面板添加點擊事件監聽器,當面板被點擊時,執行toggleOpen函數。
為每個面板添加過渡效果結束事件監聽器,當過渡效果結束時,執行toggleActive函數。
const panels = document.querySelectorAll('.panel'); // 選取所有面板
function toggleOpen(){
this.classList.toggle('open'); // 切換 'open' class
}
function toggleActive(e){
if (e.propertyName.includes('flex')){
this.classList.toggle('open-active'); // 當過渡完成後切換 'open-active' class
}
}
panels.forEach(panel => panel.addEventListener('click', toggleOpen)); // 當面板被點擊時調用 toggleOpen 函數
panels.forEach(panel => panel.addEventListener('transitionend', toggleActive)); // 當過渡效果結束時調用 toggleActive 函數